<?php
//-------------------------------------------------------------------------
// OVIDENTIA http://www.ovidentia.org
// Ovidentia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//-------------------------------------------------------------------------
/**
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
 * @copyright Copyright (c) 2008 by CANTICO ({@link http://www.cantico.fr})
 */
include_once 'base.php';
require_once dirname(__FILE__).'/functions.php';




class mailspooler_mail
{
	
	private function addMail(&$mail, $list) {
		foreach($list as $arr) {
			$mail[] = $arr[0];
		}
	}
	
	/**
	 * Record mail in database from event mail infos
	 * @return unknown_type
	 */
	public function recordMail(bab_eventMail $event) {
		global $babDB;
		$addon = bab_getAddonInfosInstance('mailspooler');
		
		$attachments = array();

		if ($event->attachements) {
			
			$attachments = $event->attachements;

			$dir = $addon->getUploadPath().'/mail/';
			if (!is_dir($dir)) {
				bab_mkdir($dir);
			}

			foreach($event->attachements as $k => $arr) {
				$newname = $dir.md5(uniqid(rand(), true));
				if (is_file($arr[0])) {
					copy($arr[0], $newname);
					$attachments[$k][0] = $newname;
				}
			}
		}

		$recipients = array();
		$this->addMail($recipients, $event->to);
		$this->addMail($recipients, $event->cc);
		$this->addMail($recipients, $event->bcc);

		$recipients = implode(', ',$recipients);

		$data = array(
				'from'		=> $event->from,
				'sender'	=> $event->sender,
				'to'		=> $event->to,
				'cc'		=> $event->cc,
				'bcc'		=> $event->bcc,
				'files'		=> $attachments
			);

		$data = serialize($data);

		if ($event instanceof bab_eventAfterMailSent)
		{
			$sent_status = $event->sent_status ? '1' : '0';
			$ErrorInfo = (string) $event->ErrorInfo;
		} else {
			$sent_status = null;
			$ErrorInfo = '';
		}

		$mail_hash = md5($event->subject.$event->body.$data);

		$res = $babDB->db_query("SELECT COUNT(*) FROM mailspooler_mail WHERE mail_hash='".$babDB->db_escape_string($mail_hash)."'");
		list($n) = $babDB->db_fetch_array($res);

		if (0 < $n) {
			
			// ignorer le principe du hash car cela empeche de renvoyer un mail a partir de la liste des mails non envoyes
			// le hash est le meme et il ne l'ajoute pas
			
			bab_debug("mail creation in spooler rejected because mail_hash allready exists : ".$mail_hash);
			return;
		}

		$babDB->db_query("INSERT INTO mailspooler_mail 
				( mail_hash, mail_subject, body, altbody, format, recipients, mail_data, sent_status, error_msg, mail_date ) 
			VALUES 
				(
					".$babDB->quote($mail_hash).",
					".$babDB->quote($event->subject).", 
					".$babDB->quote($event->body).", 
					".$babDB->quote($event->altBody).",
					".$babDB->quote($event->format).",
					".$babDB->quote($recipients).",
					".$babDB->quote($data).", 
					".$babDB->quoteOrNull($sent_status).", 
					".$babDB->quote($ErrorInfo).", 
					NOW()
				)
			");
	}
	
	
	
	
	/**
	 * Process waiting mails
	 * @throws ErrorException 
	 * @return int number of processed email
	 */
	public function sendWaiting()
	{
		include_once $GLOBALS['babInstallPath']."utilit/mailincl.php";
		
		global $babDB;

		$mail_obj = bab_mail();

		if (!$mail_obj) {
			throw new ErrorException(mailspooler_translate("Mail is not configured"));
		}

		$res = $babDB->db_query("
			SELECT * FROM mailspooler_mail WHERE sent_status IS NULL
		");
		
		$spooler = new mailspooler_mail;
		$n = 0;

		while ($arr = $babDB->db_fetch_assoc($res)) {
			if ($spooler->sendMail($mail_obj, $arr))
			{
				$n++;
			}
		}
		
		return $n;
	}
	
	
	private function addRecipient(babMail $mail, $type, $arr) {
		$function = 'mail'.$type;
	
		foreach($arr as $recipient) {
			if (isset($recipient[1])) { /* name of recipient */
				/* Add email only if it's not empty */
				if (!empty($recipient[0])) {
					$mail->$function($recipient[0], $recipient[1]);
				}
			} else {
				/* Add email only if it's not empty */
				if (!empty($recipient[0])) {
					$mail->$function($recipient[0]);
				}
			}
		}
	}
		
	
	
	/**
	 * Send a mail in table
	 * @throws ErrorException 
	 * 
	 * @param	babMail	$mail_obj
	 * @param 	Array	$arr
	 * @return unknown_type
	 */
	public function sendMail(babMail $mail_obj, Array $arr)
	{
		global $babDB;
		
		$mail_obj->clearAllRecipients();
		$mail_obj->clearReplyTo();
		
		$data = unserialize($arr['mail_data']);

		if (isset($data['from'])) {
			if (isset($data['from'][1])) {
				$mail_obj->mailFrom($data['from'][0], $data['from'][1]);
			} else {
				$mail_obj->mailFrom($data['from'][0]);
			}
		}

		$mail_obj->mailSender($data['sender']);

		$this->addRecipient($mail_obj, 'To', $data['to']);
		$this->addRecipient($mail_obj, 'Cc', $data['cc']);
		$this->addRecipient($mail_obj, 'Bcc', $data['bcc']);

		$mail_obj->mailSubject($arr['mail_subject']);
		$mail_obj->mailBody($arr['body'], $arr['format']);
		$mail_obj->mailAltBody($arr['altbody']);

		foreach($data['files'] as $file) {
			if (is_file($file[0]))
			{
				$mail_obj->mailFileAttach($file[0], $file[1], $file[2]);
			}
		}
		
		
		// call Send() without events
		
		if (!$mail_obj->mail->Send()) {
			
			$babDB->db_query("
				UPDATE mailspooler_mail SET 
					sent_status='0', 
					error_msg=".$babDB->quote($mail_obj->ErrorInfo())." 
				WHERE 
					id=".$babDB->quote($arr['id'])
			);
			
			throw new ErrorException(mailspooler_translate("Mail server error"));
			return false;
		}
		
		$mail_obj->mailClearAttachments();
		$this->deleteEmail($arr);
		return true;
	}
	
	
	/**
	 * Delete mail from table
	 * @param array $arr
	 * @return unknown_type
	 */
	public function deleteEmail(Array $arr) {
		
		global $babDB;
		
		$data = unserialize($arr['mail_data']);
			
		foreach($data['files'] as $file) {
			if (is_file($file[0]) && is_writable($file[0])) {
				unlink($file[0]);
			}
		}
		
		$babDB->db_query('
			DELETE FROM mailspooler_mail WHERE id='.$babDB->quote($arr['id']).'
		');
	}
}